home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / unix / unz50p1.zoo / mapname.c < prev    next >
C/C++ Source or Header  |  1992-08-12  |  16KB  |  375 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   mapname.c
  4.  
  5.   This routine changes DEC-20, VAX/VMS, and DOS-style filenames into normal
  6.   Unix names (and vice versa, in some cases); it also creates any necessary 
  7.   directories, if the -d switch was specified.
  8.  
  9.   ---------------------------------------------------------------------------
  10.  
  11.   Notes:
  12.  
  13.      - This routine REALLY needs to be rewritten (different routines for
  14.        each output OS, with different rules for different parts of the path
  15.        name).  If each zip program stores local-format names (like the VMS
  16.        one did at one time), it would probably be best to convert to an in-
  17.        termediate format first (assuming we're not extracting under the same
  18.        OS as that under which the zipfile was created), then from that to
  19.        the current operating system's format.
  20.      - The strcpy and strcat operations on both cdp and filename may over-
  21.        write memory, since they don't check lengths.  With a kilobyte in
  22.        which to work, this is probably not that big a deal, but it could
  23.        cause problems eventually.
  24.  
  25.   ---------------------------------------------------------------------------*/
  26.  
  27.  
  28. #include "unzip.h"
  29.  
  30.  
  31. /*******************/
  32. /* Mapname Defines */
  33. /*******************/
  34.  
  35. #ifdef VMS
  36. #  define PERMS   0
  37. #else
  38. #  define PERMS   0777
  39. #endif
  40.  
  41. #ifndef NO_MKDIR
  42. #  if (defined(DOS_OS2) && !defined(__GO32__))
  43. #    if (_MSC_VER >= 600)       /* have special MSC mkdir prototype */
  44. #      include <direct.h>
  45. #    else                       /* own prototype because dir.h conflicts? */
  46.        int mkdir(const char *path);
  47. #    endif /* ?(MSC 6.0 or later) */
  48. #    define MKDIR(path,mode)   mkdir(path)
  49. #  else /* !DOS_OS2 || __GO32__ */
  50. #    ifdef MACOS
  51. #      define MKDIR(path,mode)   macmkdir(path,gnVRefNum,glDirID)
  52. #    else /* !MACOS */
  53. #      define MKDIR(path,mode)   mkdir(path,mode)
  54. #    endif /* ?MACOS */
  55. #  endif /* ?(DOS_OS2 && !__GO32__)  */
  56. #endif /* !NO_MKDIR */
  57.  
  58.  
  59.  
  60.  
  61. /************************/
  62. /*  Function mapname()  */
  63. /************************/
  64.  
  65. int mapname(create_dirs)   /* return 0 if no error, 1 if caution (filename */
  66.     int create_dirs;       /*  truncated), 2 if warning (skip file because */
  67. {                          /*  dir doesn't exist), 3 if error (skip file) */
  68. #ifdef NO_MKDIR
  69.     char command[FILNAMSIZ+40]; /* buffer for system() call */
  70. #endif
  71. #ifdef VMS
  72.     int stat_val;               /* temp. holder for stat() return value */
  73.     char *dp, *xp;              /* pointers to directory name */
  74.     char *np;                   /* pointer into filename */
  75. #endif /* VMS */
  76. #ifdef DOS_VMS
  77.     char *last_dot=NULL;        /* last dot not converted to underscore */
  78. #endif /* DOS_VMS */
  79. #ifdef OS2
  80.     char *last;
  81.     extern char longfilename[]; /*  AFTER file created and closed */
  82.     extern int longname;        /* used also in file_io.c:  set EAs */
  83.     int longdir;
  84. #endif /* OS2 */
  85.     char name[FILNAMSIZ];       /* file name buffer */
  86.     char *pp, *cp, *cdp;        /* character pointers */
  87.     char delim = '\0';          /* directory delimiter */
  88.     int quote = FALSE;          /* flags */
  89.     int indir = FALSE;
  90.     int done = FALSE;
  91.     int created = FALSE;
  92.     register unsigned workch;   /* hold the character being tested */
  93.  
  94.  
  95. /*---------------------------------------------------------------------------
  96.     Initialize various pointers and counters and stuff.
  97.   ---------------------------------------------------------------------------*/
  98.  
  99. #ifdef MAP_DEBUG
  100.     fprintf(stderr, "%s ", filename);   /* echo name of this file */
  101. #endif
  102.     cdp = (char *)NULL;
  103.     pp = name;                  /* point to translation buffer */
  104.     *name = '\0';               /* initialize buffer */
  105.     if (!jflag) {               /* -j => junk pathnames */
  106.         cdp = (char *)malloc(strlen(filename) + 3);   /* place for holding */
  107.         if (cdp == (char *)NULL) {                    /*  directory name */
  108.             fprintf(stderr, "mapname:  out of memory [%s]\n", filename);
  109.             return 3;
  110.         }
  111. #ifdef VMS
  112.         *cdp++ = '[';
  113.         xp = cdp;               /* always points to last non-NULL char */
  114.         *cdp++ = '.';
  115. #endif /* VMS */
  116. #ifdef MACOS
  117.         *cdp = ':';             /* the Mac uses ':' as a directory separator */
  118.         cdp[1] = '\0';
  119. #else /* !MACOS */
  120.         *cdp = '\0';
  121. #endif /* ?MACOS */
  122.     }
  123.  
  124. /*---------------------------------------------------------------------------
  125.     Begin main loop through characters in filename.
  126.   ---------------------------------------------------------------------------*/
  127.  
  128.     for (cp = filename; (workch = (unsigned char) *cp++) != 0  &&  !done;) {
  129.  
  130.         if (quote) {                 /* if char quoted, */
  131.             *pp++ = (char) workch;   /*  include it literally */
  132.             quote = FALSE;
  133.         } else if (indir) {          /* if in directory name, */
  134.             if (workch == (unsigned)delim)  /*  look for end delimiter */
  135.                 indir = FALSE;
  136.         } else
  137.             switch (workch) {
  138.             case '<':                /* discard DEC-20 directory name */
  139.                 indir = TRUE;
  140.                 delim = '>';
  141.                 break;
  142.             case '[':                /* discard VMS directory name */
  143.                 indir = TRUE;
  144.                 delim = ']';
  145.                 break;
  146.             case '/':                /* discard Unix path name  */
  147.             case '\\':               /*  or MS-DOS path name... */
  148.                                      /*  iff -j flag was given  */
  149.                 /*
  150.                  * Special processing case:  if -j flag was not specified on
  151.                  * command line and create_dirs is TRUE, create any necessary
  152.                  * directories included in the pathname.  Creation of dirs is
  153.                  * straightforward on BSD and MS-DOS machines but requires use
  154.                  * of the system() command on SysV systems (or any others which
  155.                  * don't have mkdir()).  The stat() check is necessary with
  156.                  * MSC because it doesn't have an EEXIST errno, and it saves
  157.                  * the overhead of multiple system() calls on SysV machines.
  158.                  */
  159.  
  160.                 if (!jflag) {
  161.                     *pp = '\0';
  162. #ifdef VMS
  163.                     dp = name;
  164.                     while (*++xp = *dp++);  /* copy name to cdp */
  165.                     last_dot = NULL;        /* dir name:  no dots allowed */
  166.                     strcpy(xp, ".dir");     /* add extension for stat check */
  167.                     stat_val = stat(cdp, &statbuf);
  168.                     *xp = '\0';             /* remove extension for all else */
  169.                     if (stat_val) {         /* doesn't exist, so create */
  170. #else /* !VMS */
  171. #ifdef MSDOS
  172.                     if (last_dot != NULL) {  /* one dot in dir name is legal */
  173.                         *last_dot = '.';
  174.                         last_dot = NULL;
  175.                     }
  176. #endif /* MSDOS */
  177.                     strcat(cdp, name);
  178. #ifdef OS2
  179.                     if ((longdir = !IsFileNameValid(cdp)) != 0) {
  180.                         last = strrchr(cdp, '/');
  181.                         strcpy(longfilename, last ? last + 1 : cdp);
  182.                         fprintf(stderr, "renaming directory \"%s\"", cdp);
  183.                         ChangeNameForFAT(cdp);
  184.                         fprintf(stderr, " to \"%s\"\n", cdp);
  185.                     }
  186. #endif /* OS2 */
  187.                     if (stat(cdp, &statbuf)) {  /* doesn't exist, so create */
  188. #endif /* ?VMS */
  189.                         if (!create_dirs) /* told not to create (freshening) */
  190.                             return 2;
  191. #ifdef NO_MKDIR
  192.                         sprintf(command,
  193.                           "IFS=\" \t\n\" /bin/mkdir %s 2>/dev/null", cdp);
  194.                         if (system(command)) {
  195. #else /* !NO_MKDIR */
  196.                         if (MKDIR(cdp, PERMS) == -1) {
  197. #endif /* ?NO_MKDIR */
  198.                             perror(cdp);
  199.                             free(cdp);
  200.                             fprintf(stderr, "mapame:  unable to process [%s]\n",
  201.                               filename);
  202.                             return 3;
  203.